// @ts-nocheck

import isArray from '@/base/isArray'
import merge from '../object/merge'
import def from '@/object/def'
import deepClone from '@/object/deepClone'
import { _includesChildPath } from '@/_helper/_helperTreeBase'
import { TTreeToListProp } from '@/_types/_helperTreeBaseType'

/**
 * 获取节点 经过的所有父节点 轨迹节点
 * @param {Object} listObj
 * @param {string|number} ID
 * @returns {any[]}
 */
function _getNodePathItem(listObj = {}, ID = '') {
  const ids = ID.toString().split('-')
  let paths = []
  for (let i = 1; i <= ids.length; i++) {
    paths.push(ids.slice(0, i).join('-'))
  }
  paths.shift()
  paths.pop()
  return paths
    .map(v => {
      return listObj[v]
    })
    .filter(Boolean)
}

/**
 * 将tree结构 转化成 list
 * @param tree 要转换的tree数据集
 * @param props 自定义字段
 * @param {string} [props.children] 自定义字段-children属性
 * @param retainChild 是否保留每一项中的 直接子节点
 * @param retainPaths 是否返回每一项节点所经过的路径节点
 * @param retainAllChildren 是否返回每一项节点 所有的子代以及所有子代下所有节点（平铺化）
 * @param isDeepClone 是否深度克隆原树型对象
 * @param retainParent 是否深度保留父节点
 * @returns {*[]}
 */
//  Object.defineProperty(item, '_id', { writable: false, value: `${item._pId}-${index + 1}` })
function treeToList({
  tree = [] as any[],
  props = { children: 'children' } as TTreeToListProp,
  retainChild = false,
  retainPaths = false,
  retainAllChildren = false,
  isDeepClone = true,
  retainParent = false
}): any[] {
  let defaultProps = { children: 'children' }
  props = merge({}, defaultProps, props)

  if (isDeepClone) tree = deepClone(tree)

  const _list = []
  const _PID = '@'
  let _listObj = {}
  const treeToListFn = ({ tree = [], props = { children: 'children' }, retainChild = false, PID = '@' }) => {
    if (isArray(tree) && tree.length) {
      tree.forEach((item, index) => {
        let _pId = item.__pId__ ?? PID
        def(item, '__pId__', _pId)
        def(item, '__id__', `${_pId}-${index}`)
        def(item, '__prevNode__', tree[index - 1])
        def(item, '__index__', index)
        def(item, '__nextNode__', tree[index + 1])
        _list.push(item)
        if (isArray(item[props.children]) && item[props.children].length) {
          treeToListFn({
            tree: item[props.children],
            props,
            retainChild,
            PID: item.__id__
          })
        }
      })
    }
  }
  treeToListFn({ tree, props, retainChild, PID: _PID })

  if (retainPaths || retainAllChildren || retainParent) {
    _listObj = _list.reduce((pre, cur) => {
      if (cur) {
        pre[cur.__id__] = cur
      }
      return pre
    }, {})
  }

  _list.forEach(v => {
    // 是否保留每一项中的 直接子节点
    if (!retainPaths) {
      delete v[props.children]
    }

    // 是否返回每一项节点 所有的子代以及所有子代下所有节点（平铺化）
    if (retainAllChildren) {
      def(
        v,
        '__allChildren__',
        _list.filter(o => {
          if (_includesChildPath(o.__id__, v.__id__)) {
            return true
          }
          // const idx = String(o.__pId__).indexOf(v.__id__)
          // const hasChild = !!o[props.children]?.length // 是否含有子节点
          // if (!hasChild && idx == 0 && String(o.__id__).substr(v.__id__.length, 1) == '-') {
          //   return true
          // }
        })
      )
    }
    // 是否保留每一项中的 直接子节点
    if (retainPaths) {
      def(v, '__rootNode__', _listObj[v.__id__.split('-').slice(0, 2).join('-')] || v)
      def(v, '__pathNodes__', _getNodePathItem(_listObj, v.__id__))
    }
    def(v, '__level__', String(v.__pId__).split('-').length) // 当前节点处于深度（即第几层）
    if (retainParent) {
      def(v, '__parentNode__', _listObj[v.__pId__])
    }
  })

  return _list
}

export default treeToList
